#include <bits/stdc++.h>
using namespace std;
const int N = 10005;
int cnt; // 强连通分量的个数
int low[N], num[N], dfn;
int sccno[N], top; // 用St[]处理栈，top是栈顶
stack<int> s;
vector<int> G[N];
int tu[505][505];
int bianhao[505][505];
bool check[505][505];
int n, m;
void dfs(int u) {
  s.push(u);               // u进栈
  low[u] = num[u] = ++dfn; // 时间戳
  for (auto son : G[u]) {
    if (!num[son]) { // 未访问过的点，继续dfs
      dfs(son);      // dfs的最底层，是最后一个SCC
      low[u] = min(low[son], low[u]);
    } else if (!sccno[son]) // 处理回退边
      low[u] = min(low[u], num[son]);
  }
  if (low[u] == num[u]) { // 栈底的点是SCC的祖先，它的low = num
    cnt++;
    while (1) {
      int v = s.top(); // v弹出栈
      s.pop();
      sccno[v] = cnt;
      if (u == v)
        break; // 栈底的点是SCC的祖先
    }
  }
}
void Tarjan(int n) {
  cnt = top = dfn = 0;
  memset(sccno, 0, sizeof(sccno));
  memset(num, 0, sizeof(num));
  memset(low, 0, sizeof(low));
  for (int i = 1; i <= n; i++)
    if (!num[i])
      dfs(i);
}
int tttttt;
int ccnntt = 1;
void dfs(int i, int j, int color) {
  bianhao[i][j] = ccnntt;
  check[i][j] = true;
  if (i + 1 <= n && i - 1 <= n && j + 1 <= m && j - 1 <= m) {
    if (tu[i + 1][j] < color) {
      tttttt = max(tttttt, tu[i + 1][j]);
    }
    if (tu[i - 1][j] < color) {
      tttttt = max(tttttt, tu[i - 1][j]);
    }
    if (tu[i][j + 1] < color) {
      tttttt = max(tttttt, tu[i][j + 1]);
    }
    if (tu[i][j - 1] < color) {
      tttttt = max(tttttt, tu[i][j - 1]);
    }
  }
  if (!check[i][j]) {
    if (i + 1 <= n && tu[i + 1][j] && tu[i + 1][j] == tu[i][j]) {
      dfs(i + 1, j, color);
    }
    if (i - 1 >= 1 && tu[i - 1][j] && tu[i - 1][j] == tu[i][j]) {
      dfs(i - 1, j, color);
    }
    if (j + 1 <= m && tu[i][j + 1] && tu[i][j + 1] == tu[i][j]) {
      dfs(i, j + 1, color);
    }
    if (j - 1 >= 1 && tu[i][j - 1] && tu[i][j - 1] == tu[i][j]) {
      dfs(i, j - 1, color);
    }
  }
}
int main() {
  cin >> n >> m;
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      cin >> tu[i][j];
    }
  }
  int aa = 1;
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= n; j++) {
      tttttt = 0;
      dfs(i, j, aa);
      G[ccnntt].push_back(bianhao[i][j]);
      ccnntt++;
    }
  }
  Tarjan(n);
  cout << cnt / 3;
  return 0;
}